package com.springboot.frame.excel.style;


import com.springboot.frame.excel.annotation.Excel;
import com.springboot.frame.excel.annotation.ExcelAttribute;
import com.springboot.frame.excel.annotation.HeaderStyle;
import com.springboot.frame.excel.annotation.TitleStyle;
import com.springboot.frame.excel.handler.CellTypeManager;
import org.apache.poi.ss.usermodel.*;

import java.lang.reflect.Field;

/**
 * @author madman
 */
@TitleStyle
@Excel
public final class CellStyleFactory {

  /**
   * 该工厂的Class对象：主要为了获取默认表头样式注解(HeaderStyle)、表内容样式注解(ExcelAttribute)，以供后面读取默认值
   */
  private static final Class<?> INSTANCE = CellStyleFactory.class;
  /**
   * 默认Excel注解
   */
  public static final Excel EXCEL_ANNOTATION = initExcel();
  /**
   * 默认表标题注解(TitleStyle)
   */
  public static final TitleStyle TITLE_ANNOTATION = initTitle();
  /**
   * 默认表头注解(HeaderStyle)
   */
  public static final HeaderStyle HEADER_ANNOTATION = initHeader();
  /**
   * 默认表内容注解(ExcelAttribute)
   */
  public static final ExcelAttribute ATTRIBUTE_ANNOTATION = initExcelAttribute();
  /**
   * Workbook对象：其上的注解为默认表头样式注解(HeaderStyle)、表内容样式注解(ExcelAttribute)，以供后面读取默认值
   */
  @HeaderStyle
  @ExcelAttribute("")
  private Workbook workbook;


  public CellStyleFactory(Workbook workbook) {
    this.workbook = workbook;
  }

  /**
   * 获取默认Excel注解
   *
   * @return Excel注解
   */
  private static Excel initExcel() {
    return INSTANCE.getAnnotation(Excel.class);
  }

  /**
   * 获取默认表标题注解(TitleStyle)
   *
   * @return 默认表标题注解(TitleStyle)
   */
  private static TitleStyle initTitle() {
    return INSTANCE.getAnnotation(TitleStyle.class);
  }

  /**
   * 获取默认表头注解(HeaderStyle)
   *
   * @return 默认表头注解(HeaderStyle)
   */
  private static HeaderStyle initHeader() {
    try {
      return INSTANCE.getDeclaredField("workbook").getAnnotation(HeaderStyle.class);
    } catch (NoSuchFieldException e) {
      return null;
    }
  }

  /**
   * 获取默认表内容注解(ExcelAttribute)
   *
   * @return 默认表内容注解(ExcelAttribute)
   */
  private static ExcelAttribute initExcelAttribute() {
    try {
      return INSTANCE.getDeclaredField("workbook").getAnnotation(ExcelAttribute.class);
    } catch (NoSuchFieldException e) {
      return null;
    }
  }

  /**
   * 获取表标题样式
   *
   * @param titleStyle 表标题样式注解
   * @return 通过表标题样式注解获取表标题样式
   */
  public CellStyle createTitleCellStyle(TitleStyle titleStyle) {
    return createCellStyle(new AnnotationResolver(titleStyle));
  }

  /**
   * 获取表头样式
   *
   * @param headerStyleAnnotation 表头样式注解
   * @return 通过表头样式注解获取表头样式
   */
  public CellStyle createHeaderCellStyle(HeaderStyle headerStyleAnnotation) {
    return createCellStyle(new AnnotationResolver(headerStyleAnnotation));
  }

  /**
   * 获取表内容样式
   *
   * @param field 该列对于字段
   * @param excelAttribute 表内容注解
   * @return 通过表内容样式注解获取表内容样式
   */
  public CellStyle createAttributeCellStyle(Field field, ExcelAttribute excelAttribute) {
    AnnotationResolver annotationResolver = new AnnotationResolver(excelAttribute);
    CellStyle cellStyle = createCellStyle(annotationResolver);
    Class<?> type = field.getType();
    String precision = "precision";
    if (CellTypeManager.isDateType(type)) {
      cellStyle.setDataFormat(
          workbook.createDataFormat().getFormat((String) annotationResolver.resolve("dateFormat")));
    } else if (CellTypeManager.isPrecisionType(type)) {
      StringBuilder str = new StringBuilder("0.");
      for (int i = 0; i < Math.abs((int) annotationResolver.resolve(precision)); i++) {
        str.append("0");
      }
      cellStyle.setDataFormat(workbook.createDataFormat().getFormat(str.toString()));
    }
    return cellStyle;
  }

  /**
   * 创建单元式样式
   *
   * @param annotationResolver 注解解析器
   * @return 单元格样式
   */
  private CellStyle createCellStyle(AnnotationResolver annotationResolver) {
    CellStyle cellStyle = workbook.createCellStyle();
    Font font = workbook.createFont();
    font.setFontName((String) annotationResolver.resolve("fontName"));
    font.setFontHeightInPoints((short) annotationResolver.resolve("fontSize"));
    font.setBold((boolean) annotationResolver.resolve("fontBold"));
    font.setColor(((IndexedColors) annotationResolver.resolve("fontColor")).getIndex());
    font.setStrikeout((boolean) annotationResolver.resolve("fontStrikeout"));
    font.setItalic((boolean) annotationResolver.resolve("fontItalic"));
    boolean underLine = annotationResolver.resolve("fontUnderLine");
    font.setUnderline(underLine ? (byte) 1 : (byte) 0);
    cellStyle.setFont(font);
    cellStyle.setWrapText((boolean) annotationResolver.resolve("wrapText"));
    cellStyle.setAlignment((HorizontalAlignment) annotationResolver.resolve("horizontal"));
    cellStyle.setVerticalAlignment((VerticalAlignment) annotationResolver.resolve("vertical"));
    BorderStyle borderStyle = annotationResolver.resolve("borderStyle");
    cellStyle.setBorderBottom(borderStyle);
    cellStyle.setBorderLeft(borderStyle);
    cellStyle.setBorderTop(borderStyle);
    cellStyle.setBorderRight(borderStyle);
    cellStyle.setFillPattern((FillPatternType) annotationResolver.resolve("fillPatternType"));
    cellStyle.setFillForegroundColor(
        ((IndexedColors) annotationResolver.resolve("fillColor")).getIndex());
    return cellStyle;
  }

}
